﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading;
using System.Windows.Forms;
using System.Configuration;

namespace StockAnalyzer.Core
{
    internal abstract class Graber
    {
        private readonly DateTime from;
        private readonly StockCollection stocks;
        private readonly DateTime to;

        protected Graber(StockCollection stocks, DateTime from, DateTime to)
        {
            this.stocks = stocks;
            this.from = from;
            this.to = to;
        }

        public void GetHistory()
        {
            //List<Thread> list = new List<Thread>();
            foreach (Stock s in stocks)
            {
                var t = new Thread(executeGetPriceHistory);
                t.Start(new object[] { s, from, to });
                t.Join();
            }
            //foreach (var t in list)
            //{
            //    t.Join();
            //}
        }

        private void executeGetPriceHistory(object data)
        {
            var args = (object[])data;
            getPriceHistory((Stock)args[0], (DateTime)args[1], (DateTime)args[2]);
        }

        protected abstract void getPriceHistory(Stock stock, DateTime from, DateTime to);
    }

    internal class YahooGraber : Graber
    {
        private string StorePath
        {
            get
            {
                string path = Application.StartupPath + "\\YahooGraber\\Cache";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                return path;
            }
        }

        public YahooGraber(StockCollection stocks, DateTime from, DateTime to)
            : base(stocks, from, to)
        {
        }

        protected override void getPriceHistory(Stock stock, DateTime from, DateTime to)
        {
            try
            {
                byte[] content = download(stock.Symbol, from, to);
                parse(stock, content);
            }
            catch (Exception)
            {
            }
        }

        private static void parse(Stock stock, byte[] content)
        {
            var stream = new MemoryStream(content);
            var reader = new StreamReader(stream);
            try
            {
                reader.ReadLine(); // 头
                while (stream.Position != stream.Length)
                {
                    string[] items = reader.ReadLine().Split(new char[] { ',' });
                    if (items.Length == 7) //总共有7列
                    {
                        DateTime date = DateTime.Parse(items[0]);
                        double open = double.Parse(items[1]);
                        double high = double.Parse(items[2]);
                        double low = double.Parse(items[3]);
                        double close = double.Parse(items[4]);
                        Int64 volume = Int64.Parse(items[5]);

                        stock.History.Add(new Tick(date, open, close, high, low, volume));
                    }
                }
            }
            finally
            {
                stream.Close();
            }
        }

        private byte[] download(string symbol, DateTime from, DateTime to)
        {
            //var url = @"http://ichart.finance.yahoo.com/table.csv?s=AXP&a=03&b=1&c=1928&d=06&e=18&f=2009&g=d&ignore=.csv";
            //var url = @http://ichart.yahoo.com/table.txt?s=^DJI&a=6&b=23&c=2009&d=6&e=24&f=2009&y=0&g=d&ignore=.txt
            string url = @"http://ichart.yahoo.com/table.txt?"
                         + "s=" + symbol
                         + "&a=" + (from.Month - 1).ToString()
                         + "&b=" + from.Day.ToString()
                         + "&c=" + from.Year.ToString()
                         + "&d=" + (to.Month - 1).ToString()
                         + "&e=" + to.Day.ToString()
                         + "&f=" + to.Year.ToString()
                         + "&y=0&g=d&ignore=.txt";
            var client = new WebClient();
            if (ConfigurationManager.AppSettings["ProxyFlag"] == "1")
            {
                string proxyAddress = ConfigurationManager.AppSettings["ProxyAddress"];
                int proxyPort = int.Parse(ConfigurationManager.AppSettings["ProxyPort"]);
                client.Proxy = new WebProxy(proxyAddress, proxyPort);
            }
            return client.DownloadData(url);
        }
    }
}